#include "nrf24l01.h"
// #include <stdio.h>
uchar flag = 0;
uchar busy = 1;
/********************lcd1602**************************/
sbit E = P2 ^ 5;  //是否允许读写
sbit RW = P2 ^ 6; //状态（命令或者数据）P1^1开发板与nrf24l01 SCK 冲突
sbit RS = P2 ^ 7; //读写命令 P1^0开发板与nrf24l01 CE 冲突

// 写一个命令
void WriteCMD(uchar x) //命令函数
{
    RS = 0; //命令状态
    RW = 0; //写命令
    P0 = x; // 命令编码/0x01清屏
    E = 1;  // 允许写入
    DelayMS(5);
    E = 0; //关闭写入
}
// 写一个字节
void WriteData(uchar x)
{
    RS = 1; //数据状态
    RW = 0; //写命令
    P0 = x; // 数据内容
    E = 1;  // 允许写入
    DelayMS(5);
    E = 0; //关闭写入
}
void LCD_Init()
{
    WriteCMD(0x01); //清屏
    WriteCMD(0x38); //
    WriteCMD(0x0f); //显示开，开光标，闪烁
    WriteCMD(0x06); //屏幕不动，字符后移
}

//--定义SPI要使用的 IO--//
sbit MOSIO = P3 ^ 4;
sbit R_CLK = P3 ^ 5;
sbit S_CLK = P3 ^ 6;

/******************LCD1602显示方法***************/
/**
 * @brief	显示字符串
 * @param	x:1,2 y:1,2  str输出内容
 * @retval	None
 */
void WriteStr(unsigned char x, unsigned char y, unsigned char *str)
{
    uchar i = 0;
    if (x == 1)
    {
        WriteCMD(0x80 | y - 1);
    }
    if (x == 2)
    {
        WriteCMD(0xc0 | y - 1);
    }
    //输出字符串
    while (*str != '\n')
    {
        switch (i)
        {
        case 1:
            WriteData(':');
            break;
        case 2:
            WriteData('.');
            break;
        default:
            break;
        }
        i++;
        if (*str >= 'A') //跟A比较插入空格
            WriteData(*str);
        else
            WriteData(*str + 0x30);
        str++;
    }
}
void LCD_Show(uchar *str)
{
    switch (*str)
    {
    case 'A':
        WriteStr(1, 1, str);
        break;
    case 'B':
        WriteStr(1, 10, str);
        break;
    case 'C':
        WriteStr(2, 1, str);
        break;
    case 'D':
        WriteStr(2, 10, str);
        break;
    default:
        break;
    }
    WriteData('V');
}
//------------------------------
//         定时器0初始化
//------------------------------
void ET0_init()
{
    TMOD &= 0xf0;               //定时器0 T0
    TMOD |= 0x01;               //T0 工作方式1 16位定时器;第2~8bit原来是什么还是什么，不影响，第1bit赋值为1
    TH0 = (65536 - 2000) / 256; //2ms溢出
    TL0 = (65536 - 2000) % 256;
    ET0 = 1; //定时器0 T0中断允许
    TR0 = 1; //打开定时器0 T0
}
/******************串口打印*****************
 * printf用的话去掉REN、ES、EA***************/

void Uart_Init() //初始化函数
{
    SCON = 0x50; //0x40:0100 0000;0x60:0110 0000什么中断都没了只是输出
                 //含义：
                 //SM0、SM1=01；10位异步收发器（8位数据）
                 //SM2=0 不管RB8第九位接收数据是0或1，都接收数据并产生中断；1时数据是1才接收中断，否则抛弃
                 //REN=0 不允许接收
                 //TB8 RB8发送、接收第9位都是0
                 //TI=0、RI=0,不允许发送和接收中断
                 //0x50:0101 0000,允许接收数据；串口通信工作方式1
    PCON = 0;    //不加倍 SMOD=0
    TMOD = 0x20; //定时器1的工作方式2,8位,自动重装初始值
    TH1 = 0xfd;  //波特率9600
    TL1 = 0xfd;
    TR1 = 1; //打开计数器
    // 串口接收中断用
    // TI = 1; //串口发送数据后允许请求中断
    // REN = 1; //允许接收
    ES = 1; //允许串口中断
}
void UartSend(uchar str)
{
    if (str >= 'A') //跟A比较插入空格
    {
        SBUF = str; //串口发出标记数据
    }
    else //显示、发送数字
    {
        SBUF = str + 0x30;
    }
    // SBUF = 10;
}
void UartSendString(uchar *str)
{
    while (*str != '\n')
    {
        if (*str < 'A')
        {
            SBUF = *str + 0x30;
            str++;
        }
        else
            SBUF = *str++;
        DelayMS(5);
    }
}
/**************************************************
函数：main()
描述：
    主函数
/**************************************************/
void main(void)
{
    uchar i = 0;
    Uart_Init();
    LCD_Init();      // 初始化lcd
    Nrf24l01_Init(); // 初始化IO
    RX_Mode();       // 设置为接收模式
    ET0_init();
    EA = 1; //打开总中断
    while (1)
    {
        sta = SPI_Read(STATUS); // 读状态寄存器
        if (RX_DR)              // 判断是否接受到数据
        {
            SPI_Read_Buf(RD_RX_PLOAD, RX_BUF, TX_PLOAD_WIDTH); // 从RX FIFO读出数据
            SPI_RW_Reg(FLUSH_RX, 0xFF);                        // **重要**清除RX FIFO寄存器
            flag = 1;
        }
        SPI_RW_Reg(WRITE_REG + STATUS, sta); // 清除RX_DS中断标志
    }
}
void ET0_INT() interrupt 1
{
    TH0 = (65536 - 2000) / 256; // 重装初值
    TL0 = (65536 - 2000) % 256;
    if (flag) // 接受完成
    {
        UartSendString(RX_BUF);
        LCD_Show(RX_BUF);
        flag = 0;
    }
}
/*******************************
 * 串口中断
 * 当串口接收到数据的时候触发
********************************/
void uartTimer1(void) interrupt 4
{
    // uchar temp;
    // if (RI)
    // {
    //     RI = 0;
    //     temp = SBUF;
    //     SBUF = temp;
    // }
    if (TI)
    {
        TI = 0;
        busy = 0;
    }
}